<script setup lang="ts" name="GoodsSku">
import {GoodsInfo,Spec,SpecValue} from '@/types/goods'
import bwPowerSet from '@/utils/bwPowerset'
const props = defineProps<{
    goods:GoodsInfo
    skuId?:string
}>()
const emit = defineEmits<{
  (e: 'changeSku', skuId: string): void
}>()
// 修改按钮选中状态
// spac是每一行  specValue是每一行的每个按钮
const changeSelected = (spec:Spec,specValue:SpecValue) => {
    if(specValue.disabled) return
    // 如果选中了 点击就取消 为fase
    if(specValue.selected) {
        specValue.selected = false
    }else {
        // 如果没有选中  点击的时候  就排他  先干掉所有人
        spec.values.forEach(v => v.selected = false)
        // 在复活我自己
        specValue.selected = true
    }
//    const arr = getSelectedSpec()
//    console.log(arr)
// 一旦按钮被重新选择了  按钮状态也会随之需要更新
    updateDisabledStatus()
   
  // (1) 判断, 是否所有可选规格, 都选择
  const selectedArr = getSelectedSpec().filter((item) => item)
  if (selectedArr.length === props.goods.specs.length) {
    // (2) 说明全部选中, 将得到的数组, 转成字符串, 去pathMap中找对应skuId
    const key = selectedArr.join(SPLIT_STR) // '蓝色+10cm+中国'
    const result = pathMap[key]
    const skuId = result[0] // 这个skuId, 是result中的唯一值
    emit('changeSku', skuId)
  }
}
type PathMapObj = {
  [key: string]: string[]
}
const SPLIT_STR = '+'
// 基于数据 得到路径字典
const getPathMap = () => {
    const pathMap:PathMapObj = {}
    // 过滤所有的skus  得到有效的sku （库存 > 0）
    const skus = props.goods.skus.filter((item) => item.inventory > 0)
    //遍历有效的sku 获取sku的子集 进行处理
    skus.forEach((sku) => {
        // 整理数据 整理得到 [属性1，属性2，属性3]
        const arr = sku.specs.map((item)=> item.valueName)
        // 基于整理的属性列表 求子集
        const powerSet = bwPowerSet(arr)
        // 遍历子集  将子集的数据  往pathMap中整理
        // 1 如果筛选条件  不存在  新开一个属性 存
        // 2 如果筛选条件  已存在  在已有属性上 加
        // console.log(powerSet);
        powerSet.forEach((sub)=> {
            // 将数组的信息 拼成一个字符串  将来作为建（sku.id作为值）
            const key = sub.join(SPLIT_STR)
            // 判断键在对象中是否存在
            if(key in pathMap) {
                // 已存在  在已存在属性值上累加
                pathMap[key].push(sku.id)
            }else {
                // 不存在  直接新开一个属性  属性值 是一个有一项内容的数组
                pathMap[key] = [sku.id]

            }
        })
        
    })
    return pathMap
}
// 更新启用禁用状态
const updateDisabledStatus = () => {
    const selectArr = getSelectedSpec()
    // 根据路径字典  更新所有的按钮specValue状态
    props.goods.specs.forEach((spec,index) => {
        spec.values.forEach((specValue) => {
            const tempArr = [...selectArr]
            tempArr[index] = specValue.name
            const key = tempArr.filter((item) => item).join(SPLIT_STR)
           if(key in pathMap) {
            //    存在  说明有库存 不禁用
               specValue.disabled = false
           }else {
            //    不存在  说明没有库存 禁用
               specValue.disabled = true
           }
            
        })
    })
}
// 获取当前的选中状态
const getSelectedSpec = () => {
    // 根据现有的所有的按钮  进行遍历  将选中的值 按照下标存入数组
    const arr = ['','','']
    props.goods.specs.forEach((spec,index) => {
        const tempObj = spec.values.find((specValue) => specValue.selected)
        arr[index] = tempObj ? tempObj.name : ''
    })
    return arr
}
// 默认根据父传子, 传递的skuId, 进行回显, 设置选中状态
const initSelectedSpec = () => {
  if (!props.skuId) return
  const sku = props.goods.skus.find((item) => item.id === props.skuId)

  if (!sku) return
  // 基于sku.specs, 让按钮设置成选中状态
  // 三排按钮, 一排一排的来
  props.goods.specs.forEach((spec, index) => {
    // find, 每一排其实, 只会有一个被选中
    const text = sku.specs[index].valueName
    const specValue = spec.values.find((item) => item.name === text)
    specValue!.selected = true
  })
}
// 获取路径字典
const pathMap = getPathMap()
// 更新禁用状态
// 2. 先按照skuId进行初始化, 将选中状态设置好
initSelectedSpec()
// 3. 根据目前已经选中的项 => 更新禁用状态
updateDisabledStatus()
// console.log(pathMap)


</script>
<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.name">
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="sub in item.values" :key="sub.name">
          <!-- 有图片渲染图片 -->
          <img  :class="{selected:sub.selected,disabled:sub.disabled}" @click="changeSelected(item,sub)"  v-if="sub.picture" :src="sub.picture" alt="" :title="sub.name" />
          <!-- 有的会没有图片  如果没有图片的话就渲染他的名字 -->
          <span :class="{selected:sub.selected,disabled:sub.disabled}" @click="changeSelected(item,sub)"  v-else>{{ sub.name }}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>

